package org.xxpay.pay.mq.queue;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;
import org.xxpay.core.common.constant.MchConstant;
import org.xxpay.core.common.util.DateUtil;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.entity.StatisticsMch;
import org.xxpay.pay.mq.MqConfig;
import org.xxpay.pay.service.CommonService;
import org.xxpay.service.dao.mapper.StatisticsMchMapper;

import javax.jms.Queue;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Component
public class MqQueue4MchStatistics {

    private static final MyLog _log = MyLog.getLog(MqQueue4MchStatistics.class);

    @Autowired
    private JmsTemplate jmsTemplate;

    @Autowired
    private Queue mchStatisticsQueue;

    @Autowired
    private CommonService commonService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /** 发送消息 **/
    public void send(JSONObject object) {

        //是否需要订单去重
        if (object.getBoolean("isNeedRemoveDup")) {
            //从redis中查询当前订单是否已处理
            String cacheValue = stringRedisTemplate.opsForValue().get(object.getString("orderId") + "_mch_" + object.getInteger("orderStatus"));
            if (StringUtils.isNotBlank(cacheValue)) {
                _log.info(">>>>>> 当前订单商户统计已完成，无需重复发送，cacheValue：{}", cacheValue);
                return;
            }
        }

        this.jmsTemplate.convertAndSend(mchStatisticsQueue, object.toJSONString());
    }

    /**
     * 接收 更新商户统计的消息  msg内容如下：
     *  orderType--订单类型，1-支付  2-代付  3-充值
     * */
    @JmsListener(destination = MqConfig.MCH_STATISTICS)
    public void receive(String msg) {
        _log.info("成功接收更新商户统计通知, msg={}", msg);
        JSONObject orderJSON = JSONObject.parseObject(msg);
        Byte orderType = orderJSON.getByte("orderType");
        Byte orderStatus = orderJSON.getByte("orderStatus");
        Long mchId = orderJSON.getLong("mchId");
        int count;

        try {
            StatisticsMch updateRecord = new StatisticsMch();
            updateRecord.setMchId(mchId);
            updateRecord.setStatisticsDate(orderJSON.getDate("statisticsDate"));//统计日期

            if (orderType == MchConstant.ORDER_TYPE_PAY && orderStatus == MchConstant.ORDER_STATUS_INIT) {
                //支付订单  下单
                updateRecord.setPayTotalCount(orderJSON.getInteger("totalCount"));//订单总数
                updateRecord.setPayTotalAmount(orderJSON.getLong("totalAmount"));//收款总金额

            }else if (orderType == MchConstant.ORDER_TYPE_PAY && orderStatus == MchConstant.ORDER_STATUS_SUCCESS) {
                //支付订单  支付成功
                updateRecord.setPayTotalAmount(orderJSON.getLong("totalAmount"));//收款金额差值
                updateRecord.setPaySuccessCount(orderJSON.getInteger("successCount"));//成功订单总数
                updateRecord.setPaySuccessAmount(orderJSON.getLong("successAmount"));//收款成功金额
                updateRecord.setPayTotalFee(orderJSON.getLong("fee"));//商户手续费

            }else if (orderType == MchConstant.ORDER_TYPE_AGENTPAY && orderStatus == MchConstant.ORDER_STATUS_INIT) {
                //代付订单  申请
                updateRecord.setAgentPayTotalCount(orderJSON.getInteger("totalCount"));//代付订单总数
                updateRecord.setAgentPayTotalAmount(orderJSON.getLong("totalAmount"));//代付总金额

            }else if (orderType == MchConstant.ORDER_TYPE_AGENTPAY && orderStatus == MchConstant.ORDER_STATUS_SUCCESS) {
                //代付订单  成功
                updateRecord.setAgentPaySuccessCount(orderJSON.getInteger("successCount"));//代付成功订单数
                updateRecord.setAgentPaySuccessAmount(orderJSON.getLong("successAmount"));//代付成功金额
                updateRecord.setAgentPayTotalFee(orderJSON.getLong("fee"));//代付手续费

            }else if (orderType == MchConstant.ORDER_TYPE_RECHARGE && orderStatus == MchConstant.ORDER_STATUS_INIT) {
                //线下充值初始化
                updateRecord.setRechargeTotalCount(orderJSON.getInteger("totalCount"));//充值订单总数
                updateRecord.setRechargeTotalAmount(orderJSON.getLong("totalAmount"));//充值总金额

            }else if (orderType == MchConstant.ORDER_TYPE_RECHARGE && orderStatus == MchConstant.ORDER_STATUS_SUCCESS) {
                //线下充值成功
                Byte rechargeType = orderJSON.getByte("rechargeType");//0-平台给商户代充   1-审核通过商户线下充值
                if (rechargeType == 0) {
                    updateRecord.setRechargeTotalCount(orderJSON.getInteger("totalCount"));//充值订单总数
                    updateRecord.setRechargeTotalAmount(orderJSON.getLong("totalAmount"));//充值总金额
                }
                updateRecord.setRechargeSuccessCount(orderJSON.getInteger("successCount"));//充值成功订单总数
                updateRecord.setRechargeSuccessAmount(orderJSON.getLong("successAmount"));//充值成功金额
                updateRecord.setRechargeTotalFee(orderJSON.getLong("fee"));//充值手续费

            }

            count = commonService.statisticsMchService.updateStatistics(updateRecord);
            if (count == 1) {
                setCacheValue(orderJSON);
                _log.info("商户统计已更新");
            }else if (count == 0) {
                try {
                    count = commonService.statisticsMchService.add(updateRecord);
                    if (count == 1) {
                        setCacheValue(orderJSON);
                        _log.info("商户统计已初始化");
                    }
                }catch (Exception e2) {
                    send(orderJSON);
                }
            }
        }catch (Exception e) {
            _log.error(e, "处理更新商户统计失败{}");
        }
    }


    void setCacheValue(JSONObject orderJSON) {
        //是否需要订单去重
        if (orderJSON.getBoolean("isNeedRemoveDup")) {
            //存入redis，表示当前订单，商户统计已处理
            stringRedisTemplate.opsForValue().set(orderJSON.getString("orderId") + "_mch_" + orderJSON.getByte("orderStatus"), "1", 1, TimeUnit.DAYS);
        }
    }


}
